package com.ruoyi.common.utils;

import com.ruoyi.common.config.thread.AbstractWork;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

/**
 * @Author li long
 * @Date 2022/9/19
 * @Version V1.0.0
 * @Description
 */
@Slf4j
public class YouTianThreadPool {
    /**
     * 线程池 核心线程 最大线程个数
     */
    private static final int threadNum = 10;
    /**
     * 线程空闲时间
     */
    private static final int aliveTime = 5;
    /**
     * 线程池最大任务数
     */
    private static final int maxTaskNum = 5000;
    /**
     * 放入任务队列自旋次数
     */
    private static final int offerQueueNum = 3;

    private static final String THREAD_NAME = "异步动作专用线程池";

    /**
     * 线程工厂
     */
    private static final ThreadFactory THREAD_FACTORY = r -> new Thread(r, THREAD_NAME);

    /**
     * 拒绝策略
     */
    private static final RejectedExecutionHandler HANDLER = (runable, executor) -> {
        /**
         *  重新放入任务队列
         */
        for (int i = 0; i < offerQueueNum; i++) {
            if (executor.getQueue().offer(runable)) {
                break;
            }
            try {
                Thread.sleep(30000);
            } catch (InterruptedException e) {
                /**
                 *
                 */
                String threadName = Thread.currentThread().getName();
                AbstractWork work = null;
                if (runable instanceof AbstractWork) {
                    work = (AbstractWork) runable;
                }
                String description = null != work ? work.getWorkDescription() : "";
                log.error(threadName + "-" + description + "-重新放入任务队列异常,{}", e);
            }
        }

    };

    private static final ThreadPoolExecutor PATROL_POOL = new ThreadPoolExecutor(threadNum, threadNum, aliveTime, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(maxTaskNum), THREAD_FACTORY, HANDLER);

    public static ThreadPoolExecutor getPatrolPool() {
        return PATROL_POOL;
    }
}
